package es.ugr.beequizz.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import es.ugr.beequizz.bean.PreguntaBean;
import es.ugr.beequizz.bean.ValidacionBean;
import es.ugr.beequizz.converter.IncluirPreguntaConverter;
import es.ugr.beequizz.dto.IdDTO;
import es.ugr.beequizz.dto.IncluirPreguntaDTO;
import es.ugr.beequizz.dto.PreguntaDTO;
import es.ugr.beequizz.dto.PreguntaModificadaDTO;
import es.ugr.beequizz.dto.ResultadoDTO;
import es.ugr.beequizz.dto.ValidarDTO;
import es.ugr.beequizz.model.Pregunta;
import es.ugr.beequizz.model.Usuario;
import es.ugr.beequizz.services.PreguntaService;
import es.ugr.beequizz.services.RespuestaService;
import es.ugr.beequizz.services.UsuarioService;

@Controller
@RequestMapping(value = "/pregunta")
public class PreguntaController {
	
	@Autowired
	private PreguntaService preguntaService;
	
	@Autowired
	private RespuestaService respuestaService;
	
	@Autowired
	private UsuarioService usuarioService;
	
	@Autowired
	private IncluirPreguntaConverter incluirPreguntaConverter;
	
	
	@RequestMapping(value= "/incluirPregunta",method= RequestMethod.POST,
			produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public Long incluirPreguntaDTO (@RequestBody IncluirPreguntaDTO pregunta){

		Long idPregunta;
		PreguntaBean bean = incluirPreguntaConverter.convert(pregunta);
		
		bean.setFecha(new Date());
		
		final String username = SecurityContextHolder.getContext().getAuthentication().getName();
		Long idUsuario = usuarioService.recuperarIdUsuario(username);
		bean.setIdUsuario(idUsuario);
		
		idPregunta = preguntaService.incluirPregunta(bean);
		
		return idPregunta;
	}
	
	@RequestMapping(value= "/recuperarPregunta",method= RequestMethod.GET,
			produces = MediaType.APPLICATION_JSON_VALUE, params = {"preguntaId"})
	@ResponseBody
	public PreguntaModificadaDTO recuperarPregunta(@RequestParam(value = "preguntaId") Long preguntaId){
		
		final PreguntaBean pregunta = preguntaService.recuperarPregunta(preguntaId);
		PreguntaModificadaDTO dto = new PreguntaModificadaDTO();
		dto.setId(pregunta.getId());
		dto.setIdAsignatura(pregunta.getIdAsignatura());
		dto.setIdDificultad(pregunta.getIdDificultad());
		dto.setPregunta(pregunta.getPregunta());
		
		return dto;
	}
	
	@RequestMapping(value= "/modificarPregunta",method= RequestMethod.POST,
			produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public ResultadoDTO recuperarPregunta(@RequestBody PreguntaModificadaDTO dto){
		
		final PreguntaBean pregunta = new PreguntaBean();
		pregunta.setId(dto.getId());
		pregunta.setIdAsignatura(dto.getIdAsignatura());
		pregunta.setIdDificultad(dto.getIdDificultad());
		pregunta.setPregunta(dto.getPregunta());
		
		preguntaService.modificarPregunta(pregunta);
		
		return new ResultadoDTO("SUCCESS");
	}
	
	
	@RequestMapping(value= "/recuperarPreguntas",method= RequestMethod.GET,
			produces = MediaType.APPLICATION_JSON_VALUE, params = {"asignaturaId", "dificultadId"})
	@ResponseBody
	public List<PreguntaDTO> recuperarPreguntas(@RequestParam(value = "asignaturaId") Long asignaturaId,
			@RequestParam(value = "dificultadId") Long dificultadId) {
				
		List<Pregunta> preguntasBean = preguntaService.recuperarPreguntas(asignaturaId, dificultadId);
		
		List<PreguntaDTO> preguntas = new ArrayList<PreguntaDTO>();
		
		for (Pregunta pregunta : preguntasBean) {
			
			PreguntaDTO dto = new PreguntaDTO();
			dto.setId(pregunta.getId());
			dto.setEnunciado(pregunta.getEnunciado());
			dto.setValida(pregunta.isValida());
			dto.setCreador(recuperarCreador(pregunta.getCreador()));
			preguntas.add(dto);
		}

		return preguntas;
		
		
	}
	
	private String recuperarCreador(Usuario usuario) {
		return String.format("%s %s", usuario.getNombre(), usuario.getApellidos());
	}
	
	/* Metodo para suprimir preguntas*/
	@RequestMapping(value="/suprimirPregunta", method= RequestMethod.POST,
			produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public ResultadoDTO suprimirPreguntaDTO (@RequestBody String json) throws JsonParseException, JsonMappingException, IOException{
		
		final ObjectMapper mapper = new ObjectMapper();
		final List<IdDTO> idDtos = mapper.readValue(json, new TypeReference<List<IdDTO>>() {});
		try {
			for(IdDTO dto : idDtos){
				respuestaService.suprimirRespuestaIdPregunta(dto.getId());
				preguntaService.suprimirPregunta(dto.getId());
			}
			return new ResultadoDTO("SUCCESS");
			
		} catch (Exception e) {
			return new ResultadoDTO("ERROR", "Imposible de suprimir esa pregunta.");
		}
		
		
	}
	
	/* Metodo para validar preguntas*/
	@RequestMapping(value="/validacionPreguntas", method= RequestMethod.POST,
			produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public ResultadoDTO validacionPreguntas(@RequestBody String json) throws JsonParseException, JsonMappingException, IOException{
		
		final ObjectMapper mapper = new ObjectMapper();
		final List<ValidarDTO> dtos = mapper.readValue(json, new TypeReference<List<ValidarDTO>>() {});
		final List<ValidacionBean> beans = new ArrayList<ValidacionBean>();
		
		for (ValidarDTO dto : dtos){
			final ValidacionBean bean = new ValidacionBean();
			bean.setId(dto.getId());
			bean.setValido(dto.isValida());
			
			beans.add(bean);
		}
		preguntaService.validacionPregunta(beans);

		return new ResultadoDTO("SUCCESS");
		
		
	}
	

	
}
